/*
 * Copyright (C) 20015-2016 小源科技 Inc.All Rights Reserved.
 *
 * coding by 3zero
 * Description：简要描述本文件的内容
 * 
 * History：
 * 
 * 
 **/
package cn.com.xy.sms.sdk.db.entity;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import cn.com.xy.sms.sdk.Iservice.XyCallBack;
import cn.com.xy.sms.sdk.constant.Constant;
import cn.com.xy.sms.sdk.db.DBManager;
import cn.com.xy.sms.sdk.db.XyCursor;
import cn.com.xy.sms.sdk.db.base.BaseManager;
import cn.com.xy.sms.sdk.db.entity.pubinfo.NumNameManager;
import cn.com.xy.sms.sdk.db.entity.pubinfo.PubInfoManager;
import cn.com.xy.sms.sdk.log.LogManager;
import cn.com.xy.sms.sdk.net.NetUtil;
import cn.com.xy.sms.sdk.service.pubInfo.PubInfoNetService;
import cn.com.xy.sms.sdk.util.StringUtils;
import cn.com.xy.sms.sdk.util.XyUtil;

/* SDK-397 huangzhiqiang 20160524 start */
import java.util.Arrays;
import cn.com.xy.sms.sdk.db.entity.pubinfo.NumName;
/* SDK-397 huangzhiqiang 20160524 end */

/* SDK-421 huangzhiqiang 20160525 start */
import org.json.JSONArray;
import org.json.JSONObject;
/* SDK-421 huangzhiqiang 20160525 end */
/**
 * @Description:
 * 
 * @coding by 3zero
 * @version
 */
public class UpdateTaskManager {

    public static final String TASK_ID = "id";
    public static final String TASK_CONTENT = "content";
    public static final String TASK_GROUP = "t_group";
    public static final String TABLE_NAME = "tb_update_task";
    public static final String VERSION = "t_version";

    public static final String DROP_TABLE = " DROP TABLE IF EXISTS "
            + TABLE_NAME;
    public static final String CREATE_TABLE = "create table  if not exists "
            + TABLE_NAME + " (" + " id INTEGER PRIMARY KEY," + TASK_CONTENT
            + " TEXT," + TASK_GROUP + " TEXT," + VERSION + " long " + ")";
    private static final int UPLOAD_PUBINFO_SIGN_DATA_SIZE = 20;
    private static final int UPLOAD_PUBINFO_CMD_DATA_SIZE = 20;
    /* SDK-421 huangzhiqiang 20160525 start */
    private static final int UPLOAD_SHARD_DATA_SIZE = 10;
    /* SDK-421 huangzhiqiang 20160525 end */

    /* SDK-397 huangzhiqiang 20160524 start */
    public enum TaskGroup {
        /**
         * 更新公众号信息
         */
        UPDATE_PUBINFO,
        /**
         * 上传公众号签名
         */
        UPLOAD_PUBINFO_SIGN,
        /**
         * 上传退订指令
         */
        UPLOAD_PUBINFO_CMD,
        /* SDK-421 huangzhiqiang 20160525 start */
        /**
         * 上传去敏原文分片数据
         */
        UPLOAD_SHARD;
        /* SDK-421 huangzhiqiang 20160525 end */

        @Override
        public String toString() {
            switch (this) {
            case UPDATE_PUBINFO:
                return "1";
            case UPLOAD_PUBINFO_SIGN:
                return "2";
            case UPLOAD_PUBINFO_CMD:
                return "3";
            /* SDK-421 huangzhiqiang 20160525 start */
            case UPLOAD_SHARD:
                return "4";
            /* SDK-421 huangzhiqiang 20160525 start */
            default:
                return "UNKNOWN";
            }
        }
    }
    /* SDK-397 huangzhiqiang 20160524 end */

    public static void addTask(TaskInfo info) {
        try {
            ContentValues values = new ContentValues();
            values.put(TASK_CONTENT, info.content);
            values.put(TASK_GROUP, info.group);
            values.put(VERSION, info.version);
            DBManager.insert(TABLE_NAME, values);
        } catch (Throwable e) {
//            e.printStackTrace();
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, " addTask error: ", e);
            /*SDK-550 hewengao 20160719 end*/
        }
    }

    /* SDK-397 huangzhiqiang 20160524 start */
    public static void addTask(String content, TaskGroup taskGroup, int version) {
        try {
            ContentValues values = BaseManager.getContentValues(null,
                    TASK_CONTENT, content, TASK_GROUP, taskGroup.toString(), VERSION,
                    String.valueOf(version));
            DBManager.insert(TABLE_NAME, values);
        } catch (Throwable e) {
//            e.printStackTrace();
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "addTask error1: ", e);
            /*SDK-550 hewengao 20160719 end*/
        }
    }
    /* SDK-397 huangzhiqiang 20160524 end */

    // public static void deleTaskByGroup(String group){
    //
    // try {
    // DBManager.delete(TABLE_NAME, TASK_GROUP+"= ?", new String[]{group});
    //
    // } catch (Throwable e) {
    // e.printStackTrace();
    // }
    // }

    /**
     * 根据id删除数据
     * 
     * @param tid
     */
    public static void deleTaskByTid(long tid) {
        try {
            DBManager.delete(TABLE_NAME, TASK_ID + " = ?",
                    new String[] { String.valueOf(tid) });
        } catch (Throwable e) {
//            e.printStackTrace();
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "deleTaskByTid error: ", e);
            /*SDK-550 hewengao 20160719 end*/
        }
    }

    /**
     * 根据Id集合批量删除数据
     * 
     * @param taskIds
     *            需要删除的数据Id，以逗号隔开 例: 1,2,3,4
     */
    public static void deleTaskByTid(String taskIds) {
        try {
            DBManager.delete(TABLE_NAME, TASK_ID + " IN (" + taskIds + ")",
                    null);
        } catch (Throwable e) {
//            e.printStackTrace();
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "deleTaskByTid error: ", e);
            /*SDK-550 hewengao 20160719 end*/
        }
    }

    /* SDK-397 huangzhiqiang 20160524 start */
    /**
     * 查询分组的下一条数据
     * 
     * @param taskGroup
     * @return
     */
    public static TaskInfo queryNextTask(TaskGroup taskGroup) {
        XyCursor cur = null;
        try {
            String selection = TASK_GROUP + " = ?";
            if (TaskGroup.UPDATE_PUBINFO == taskGroup) {
                // 旧sdk没有设置t_group，所以要添加 OR t_group IS NULL OR t_group = '' 判断
                selection += " OR " + TASK_GROUP + " IS NULL OR " + TASK_GROUP
                        + " = '' ";
            }
            cur = DBManager.query(false, TABLE_NAME, new String[] { TASK_ID,
                    TASK_CONTENT, TASK_GROUP }, selection,
                    new String[] { taskGroup.toString() }, null, null, null, "1");

            if (cur == null || cur.getCount() < 1) {
                return null;
            }
            if (cur.moveToNext()) {
                TaskInfo info = new TaskInfo();
                info.tid = cur.getLong(cur.getColumnIndex(TASK_ID));
                info.content = cur.getString(cur.getColumnIndex(TASK_CONTENT));
                info.group = cur.getString(cur.getColumnIndex(TASK_GROUP));
                return info;
            }
        } catch (Throwable e) {
//            e.printStackTrace();
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, " queryNextTask error: ", e);
            /*SDK-550 hewengao 20160719 end*/
        } finally {
            XyCursor.closeCursor(cur, true);
        }
        return null;
    }

    /**
     * 查询分组的所有数据
     * 
     * @param taskGroup
     * @param limit
     * @return
     */
    public static List<TaskInfo> queryTaskList(TaskGroup taskGroup, int limit) {
        XyCursor cur = null;
        try {
            cur = DBManager.query(false, TABLE_NAME, new String[] { TASK_ID,
                    TASK_CONTENT, TASK_GROUP }, TASK_GROUP + " = ?",
                    new String[] { taskGroup.toString() }, null, null, null,
                    String.valueOf(limit));

            if (cur == null || cur.getCount() < 1) {
                return null;
            }
            List<TaskInfo> taskInfoList = new ArrayList<TaskInfo>();
            while (cur.moveToNext()) {
                TaskInfo info = new TaskInfo();
                info.tid = cur.getLong(cur.getColumnIndex(TASK_ID));
                info.content = cur.getString(cur.getColumnIndex(TASK_CONTENT));
                info.group = cur.getString(cur.getColumnIndex(TASK_GROUP));
                taskInfoList.add(info);
            }
            return taskInfoList;
        } catch (Throwable e) {
//            e.printStackTrace();
            /*SDK-550 hewengao 20160719 start*/
            LogManager.e(Constant.TAG, "queryTaskList error1", e);
            /*SDK-550 hewengao 20160719 end*/
        } finally {
            XyCursor.closeCursor(cur, true);
        }
        return null;
    }

    /**
     * 执行指定分组任务
     * 
     * @param taskGroup
     */
    public static synchronized void doTask(TaskGroup taskGroup) {
        try {
            if (TaskGroup.UPDATE_PUBINFO == taskGroup) {
                updatePubInfo(queryNextTask(taskGroup));
            } else if (TaskGroup.UPLOAD_PUBINFO_SIGN == taskGroup) {
                executeUploadTask(queryTaskList(taskGroup, UPLOAD_PUBINFO_SIGN_DATA_SIZE), taskGroup);
            } else if (TaskGroup.UPLOAD_PUBINFO_CMD == taskGroup) {
                executeUploadTask(queryTaskList(taskGroup, UPLOAD_PUBINFO_CMD_DATA_SIZE), taskGroup);
            } else if (TaskGroup.UPLOAD_SHARD == taskGroup) {
                /* SDK-421 huangzhiqiang 20160525 start */
                executeUploadTask(queryTaskList(taskGroup, UPLOAD_SHARD_DATA_SIZE), taskGroup);
                /* SDK-421 huangzhiqiang 20160525 end */
            }
        } catch (Throwable e) {
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, " doTask: ", e);
            /*SDK-550 hewengao 20160719 end*/
        }
    }
    /* SDK-397 huangzhiqiang 20160524 end */

    private static void updatePubInfo(final TaskInfo info) {
        if (info == null) {
            return;
        }

        final IccidInfo iccidInfo = IccidInfoManager
                .queryDeftIccidInfo(Constant.getContext());

        ArrayList<String> needUpdatePidList = PubInfoManager
                .getPostBodyIdsList(info.content);
        XyCallBack cb = new XyCallBack() {
            @Override
            public void execute(Object... obj) {
                // 回调有4种情况，
                // 1.服务端无更新，obj[0].size=0 ;
                // 2.服务端有更新，obj[0].size>0; 无论是否有更新，回调回来都要删除task
                // 3.有更新时，解析或者保存数据时抛异常，obj[0]="-1" 说明服务端返回的数据格式有问题，改更新不执行，删除task
                // 4.没有回调 服务器500错误，网络突然中断 均没有回调。下次启动时检测是否有task要更新
                deleTaskByTid(info.tid);
                /* SDK-397 huangzhiqiang 20160524 start */
                doTask(TaskGroup.UPDATE_PUBINFO);
                /* SDK-397 huangzhiqiang 20160524 end */
            }
        };

        String areaCode = "";
        String iccid = "";

        if (iccidInfo != null) {
            areaCode = iccidInfo.areaCode;
            iccid = iccidInfo.iccid;
        }
        PubInfoNetService.queryPubInfoByList(needUpdatePidList, areaCode,
                iccid, "3", cb, true);
    }

    /* SDK-397 huangzhiqiang 20160524 start */
    /**
     * 执行数据上传任务(批量)
     * 
     * @param taskInfoList 任务信息集合
     * @param taskGroup 任务类型
     */
    private static void executeUploadTask(final List<TaskInfo> taskInfoList, final TaskGroup taskGroup) {
        if (taskInfoList == null || taskInfoList.size() == 0) {
            return;
        }
        try {
            // 增强服务开关是否开启
            boolean flag = SysParamEntityManager.getBooleanParam(Constant.getContext(), Constant.SMARTSMS_ENHANCE,
                    true);
            if (!flag) {
                return;
            }
            // 任意网络
            if (XyUtil.checkNetWork(Constant.getContext(), 2) == -1) {
                return;
            }
            XyCallBack whileNetCompletedCallBack = new XyCallBack() {
                @Override
                public void execute(Object... resObjs) {
                    String deleteIds = getTaskIds(taskInfoList);
                    deleTaskByTid(deleteIds);
                    doTask(taskGroup);
                }
            };

            String dataString = null;
            if (TaskGroup.UPLOAD_PUBINFO_SIGN == taskGroup) {
                dataString = uploadPubInfoSignReqeustContent(taskInfoList);
            } else if (TaskGroup.UPLOAD_PUBINFO_CMD == taskGroup) {
                dataString = uploadCMDReqeustContent(taskInfoList);
            } else if (TaskGroup.UPLOAD_SHARD == taskGroup) {
                /* SDK-421 huangzhiqiang 20160525 start */
                dataString = uploadShardReqeustContent(taskInfoList);
                /* SDK-421 huangzhiqiang 20160525 end */
            }
            if (StringUtils.isNull(dataString)) {
                return;
            }
            NetUtil.executePubNumServiceHttpRequest(dataString, "990005", whileNetCompletedCallBack, null, false, false,
                    NetUtil.REQ_QUERY_PUBINFO, true);
        } catch (Throwable t) {
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "executeUploadPubInfo: " , t);
            /*SDK-550 hewengao 20160719 end*/
        }
    }
    /* SDK-397 huangzhiqiang 20160524 end */

    /**
     * 获取ID集合字符串，以逗号隔开
     * 
     * @param taskInfoList
     * @return
     */
    private static String getTaskIds(List<TaskInfo> taskInfoList) {
        try {
            if (taskInfoList == null || taskInfoList.size() == 0) {
                return null;
            }
            StringBuilder sbrStaskIds = new StringBuilder();
            for (TaskInfo taskInfo : taskInfoList) {
                sbrStaskIds.append(taskInfo.tid);
                sbrStaskIds.append(",");
            }
            if (sbrStaskIds.length() > 0) {
                sbrStaskIds.deleteCharAt(sbrStaskIds.length() - 1);
                return sbrStaskIds.toString();
            }
        } catch (Throwable ex) {
//            ex.printStackTrace();
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "getTaskIds: ", ex);
            /*SDK-550 hewengao 20160719 end*/
        }
        return null;
    }

    /**
     * 构建公众号明文签名上传报文(批量)
     * 
     * @param num 公众号
     * @return
     */
    private static String uploadPubInfoSignReqeustContent(
            List<TaskInfo> taskInfoList) {
        try {
            if (taskInfoList == null || taskInfoList.size() == 0) {
                return null;
            }

            /* SDK-423 huangzhiqiang 20160524 start */
            List<NumName> numNames = queryNumNameInfoByTask(taskInfoList);
            if (numNames == null || numNames.size() < 1) {
                return null;
            }
            StringBuilder sbrPubInfoSign = new StringBuilder();
            for (NumName numName : numNames) {
                if (StringUtils.isNull(numName.name)) {
                    continue;
                }
                sbrPubInfoSign.append("<num sign=\"" + numName.name + "\">");
                sbrPubInfoSign.append(numName.num);
                sbrPubInfoSign.append("</num>");
            }
            /* SDK-423 huangzhiqiang 20160524 end */

            if (sbrPubInfoSign.length() == 0) {
                return null;
            }

            StringBuilder sbrReqeustContent = new StringBuilder("<?xml version='1.0' encoding='utf-8'?>");
            sbrReqeustContent.append("<QueryPubInfoRequest>");
            sbrReqeustContent.append("<allNums type=\"1\" >");
            sbrReqeustContent.append(sbrPubInfoSign);
            sbrReqeustContent.append("</allNums>");
            sbrReqeustContent.append("</QueryPubInfoRequest>");
            return sbrReqeustContent.toString();
        } catch (Throwable e) {
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "uploadPubInfoSignReqeustContent error: ", e);
            /*SDK-550 hewengao 20160719 end*/
        }
        return null;
    }

    /**
     * 构建公众号明文退订指令上传报文(批量)
     * 
     * @param num 公众号
     * @return
     */
    private static String uploadCMDReqeustContent(
            List<TaskInfo> taskInfoList) {
        try {
            if (taskInfoList == null || taskInfoList.size() == 0) {
                return null;
            }

            /* SDK-423 huangzhiqiang 20160524 start */
            List<NumName> numNames = queryNumNameInfoByTask(taskInfoList);
            if (numNames == null || numNames.size() < 1) {
                return null;
            }
            StringBuilder sbrPubInfoCmd = new StringBuilder();
            for (NumName numName : numNames) {
                if (StringUtils.isNull(numName.cmd)) {
                    continue;
                }
                String cmdXmlArr[] = numName.cmd.split(NumNameManager.PIX);
                for (int i = 0; i < cmdXmlArr.length; i++) {
                    sbrPubInfoCmd.append(cmdXmlArr[i]);
                }
            }
            /* SDK-423 huangzhiqiang 20160524 end */

            if (sbrPubInfoCmd.length() == 0) {
                return null;
            }

            StringBuilder sbrReqeustContent = new StringBuilder("<?xml version='1.0' encoding='utf-8'?>");
            sbrReqeustContent.append("<QueryPubInfoRequest>");
            sbrReqeustContent.append("<unSubscribe type=\"1\">");
            sbrReqeustContent.append(sbrPubInfoCmd);
            sbrReqeustContent.append("</unSubscribe>");
            sbrReqeustContent.append("</QueryPubInfoRequest>");
            return sbrReqeustContent.toString();
        } catch (Throwable e) {
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "uploadCMDReqeustContent error ", e);
            /*SDK-550 hewengao 20160719 end*/
        }
        return null;
    }

    /* SDK-423 huangzhiqiang 20160524 start */
    /**
     * 根据任务集合中的号码获取号码数据
     * 
     * @param taskInfoList
     * @return
     */
    private static List<NumName> queryNumNameInfoByTask(List<TaskInfo> taskInfoList) {
        if (taskInfoList == null || taskInfoList.size() < 1) {
            return null;
        }
        List<String> allNums = new ArrayList<String>();
        for (TaskInfo taskInfo : taskInfoList) {
            if (taskInfo == null || taskInfo.content == null) {
                continue;
            }
            allNums.addAll(Arrays.asList(taskInfo.content.split(";")));
        }
        return NumNameManager.querySignInfoByNums(allNums);
    }
    /* SDK-423 huangzhiqiang 20160524 end */

    /* SDK-421 huangzhiqiang 20160525 start */
    /**
     * 构建分片数据明文上传报文(批量)
     * 
     * @param num 公众号
     * @return
     */
    private static String uploadShardReqeustContent(List<TaskInfo> taskInfoList) {
        try {
            if (taskInfoList == null || taskInfoList.size() == 0) {
                return null;
            }

            StringBuilder sbrShardItem = new StringBuilder();
            for (TaskInfo taskInfo : taskInfoList) {
                JSONArray uploadContentArr = new JSONArray(taskInfo.content);
                int length = uploadContentArr.length();
                for (int i = 0; i < length; i++) {
                    sbrShardItem.append(parseShardItem(uploadContentArr.getJSONObject(i)));
                }
            }

            if (sbrShardItem.length() == 0) {
                return null;
            }

            StringBuilder sbrReqeustContent = new StringBuilder("<?xml version='1.0' encoding='utf-8'?>");
            sbrReqeustContent.append("<QueryPubInfoRequest>");
            sbrReqeustContent.append("<shard>");
            sbrReqeustContent.append(sbrShardItem);
            sbrReqeustContent.append("</shard>");
            sbrReqeustContent.append("</QueryPubInfoRequest>");
            return sbrReqeustContent.toString();
        } catch (Throwable e) {
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "uploadShardReqeustContent: ", e);
            /*SDK-550 hewengao 20160719 end*/
        }
        return null;
    }

    /**
     * 生成分片数据上传数据报文
     * 
     * @param shardInfoJson
     * @return
     */
    private static String parseShardItem(JSONObject shardInfoJson) {
        try {
            // 分片数据不正确，直接跳过该条数据
            if (shardInfoJson == null || shardInfoJson.length() < 5) {
                return "";
            }
            StringBuilder sbrShardItem = new StringBuilder();
            sbrShardItem.append("<shardItem sign=\"");
            sbrShardItem.append(shardInfoJson.getString("contentSign")); // 去敏原文sha256签名
            sbrShardItem.append("\" attr1=\"");
            sbrShardItem.append(shardInfoJson.getString("index")); // 分组小标
            sbrShardItem.append("\" attr2=\"");
            sbrShardItem.append(shardInfoJson.getString("mod")); // 模数
            sbrShardItem.append("\" eof=\"");
            sbrShardItem.append(shardInfoJson.getString("eof")); // 短信是否结束标志(eof=-1代表结束，eof=1代表未结束)
            sbrShardItem.append("\">");
            sbrShardItem.append(shardInfoJson.getString("characterSequence")); // 需要上传的字符序列
            sbrShardItem.append("</shardItem>");
            return sbrShardItem.toString();
        } catch (Throwable e) {
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, " parseShardItem error: ", e);
            /*SDK-550 hewengao 20160719 end*/
        }
        return "";
    }
    /* SDK-421 huangzhiqiang 20160525 end */
}
